package com.gkzf.ai.module.crm.service.creditreportsimple.app;

import com.gkzf.ai.framework.common.exception.ServiceException;
import com.gkzf.ai.module.crm.controller.app.collect.vo.CollectReqVo;
import com.gkzf.ai.module.crm.controller.app.product.vo.ProductDetailsRespVO;
import com.gkzf.ai.module.crm.service.product.app.CrmProductAppService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class CollectServiceImpl implements CollectService{

    // 收藏code
    private static final String FAVORITE_KEY_PREFIX = "user:collect:";

    private static final String FAVORITE_KEY_CLICK = "user:click:";

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private CrmProductAppService productAppService;

    /**
     * 添加收藏项
     * @param collectReqVo 收藏对象
     */
    public void addFavorite(CollectReqVo collectReqVo) {
        incrementWithExpire(collectReqVo.getProductId());
        if (isFavorite(collectReqVo)) {
            removeFavorite(collectReqVo);
            return;
        }
        stringRedisTemplate.opsForZSet().add(FAVORITE_KEY_PREFIX + collectReqVo.getUserOpenId(), collectReqVo.getProductId(),System.currentTimeMillis());
    }

    /**
     * 防止重复提交
     * 第一次点击收藏 设置点击次数 并添加过期时间 5秒
     * 当5秒钟点击超过5次 则锁定1分钟
     * @param key 锁的key
     *
     */
    public void incrementWithExpire(String key) {
        // 原子性自增
        Long newValue = stringRedisTemplate.opsForValue().increment(FAVORITE_KEY_CLICK+key);
        if (newValue != null && newValue == 5L){
            throw new ServiceException(429,"请勿重复收藏！");
        }
        if (newValue != null && newValue > 6L){
            // 如果 频繁操作 锁定 1 分钟
            throw new ServiceException(429,"收藏次数频繁！");
        }
        // 设置过期时间（仅当 key 第一次创建或已过期后才需要重新设置）
        if (newValue != null && newValue == 1) {
            stringRedisTemplate.expire(FAVORITE_KEY_CLICK+key, 5, TimeUnit.SECONDS);
        }
    }

    /**
     * 获取用户的所有收藏项，按score降序排列
     * @param collectReqVo 收藏对象
     */
    public List<ProductDetailsRespVO> getCollectList(CollectReqVo collectReqVo) {
        Set<String> productIds = stringRedisTemplate.opsForZSet().reverseRange(FAVORITE_KEY_PREFIX + collectReqVo.getUserOpenId(), 0, -1);
        if (productIds != null && !productIds.isEmpty()) {
            List<Long> productIdList = productIds.stream().map(Long::parseLong).toList();
            return productAppService.getAppProductList(productIdList);
        }
        return new ArrayList<>();
    }

    /**
     * 检查某个收藏项是否存在于用户的收藏列表中
     * @param collectReqVo 收藏对象
     * @return true:已收藏;false:未收藏
     */
    public boolean isFavorite(CollectReqVo collectReqVo) {
        return stringRedisTemplate.opsForZSet().score(FAVORITE_KEY_PREFIX +  collectReqVo.getUserOpenId(), collectReqVo.getProductId()) != null;
    }

    @Override
    public Long getCollectCount(CollectReqVo collectReqVo) {
        return stringRedisTemplate.opsForZSet().size(FAVORITE_KEY_PREFIX + collectReqVo.getUserOpenId());
    }

    /**
     * 移除用户的某个收藏项
     * @param collectReqVo 收藏对象
     */
    public void removeFavorite(CollectReqVo collectReqVo) {
        stringRedisTemplate.opsForZSet().remove(FAVORITE_KEY_PREFIX + collectReqVo.getUserOpenId(), collectReqVo.getProductId());
    }
}
